package jmine.tec.scheduling.validators;

import static jmine.tec.scheduling.SchedulingMessages.VALIDATION_BEAN_DOES_NOT_EXIST;
import static jmine.tec.scheduling.SchedulingMessages.VALIDATION_INCORRECT_BEAN_TYPE;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import jmine.tec.annotations.Unmodifiable;
import jmine.tec.scheduling.Action;
import jmine.tec.scheduling.condition.Condition;
import jmine.tec.scheduling.domain.ScheduledTask;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;

import bancosys.tec.persist.validator.AbstractValidator;
import bancosys.tec.persist.validator.ValidationError;

/**
 * Validator for ScheduledTasks
 * 
 * @author lundberg
 */
@Unmodifiable
public class ScheduledTaskValidator extends AbstractValidator<ScheduledTask> implements BeanFactoryAware {

    private BeanFactory beanFactory;

    /**
     * {@inheritDoc}
     */
    @Override
    public List<ValidationError> validateInsert(ScheduledTask bean) {
        return this.validate(bean);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<ValidationError> validateUpdate(ScheduledTask bean) {
        return this.validate(bean);
    }

    /**
     * Validats a task
     * 
     * @param task task
     * @return List of validation errors
     */
    private List<ValidationError> validate(ScheduledTask task) {
        List<ValidationError> errors = new ArrayList<ValidationError>();
        errors.addAll(this.validateDependency(task.getCondition(), Condition.class));
        errors.addAll(this.validateDependency(task.getAction(), Action.class));
        return errors;
    }

    /**
     * Validades a task dependency
     * 
     * @param name name
     * @param expectedClass expectedClass
     * @return Collection of errors
     */
    private Collection<? extends ValidationError> validateDependency(String name, Class<?> expectedClass) {
        if (!this.beanFactory.containsBean(name)) {
            return Collections.singleton(new ValidationError(VALIDATION_BEAN_DOES_NOT_EXIST.create(name)));
        }
        Object bean = this.beanFactory.getBean(name);
        if (!expectedClass.isInstance(bean)) {
            return Collections.singleton(new ValidationError(VALIDATION_INCORRECT_BEAN_TYPE.create(expectedClass, bean.getClass())));
        }
        return Collections.emptyList();
    }

    /**
     * {@inheritDoc}
     */
    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }
}
